/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package isd.resto.web;

import isd.general.modelo.GR_Comprobante;
import isd.general.web.GenericBean;
import isd.inventario.modelo.ST_Producto;
import isd.inventario.web.BuscadorProductoBean;
import isd.general.util.JsfUtil;
import isd.resto.modelo.RT_ItemMovimiento;
import isd.resto.modelo.RT_Mesa;
import isd.resto.modelo.RT_MesaEstado;
import isd.resto.modelo.RT_Movimiento;
import isd.resto.modelo.RT_Mozo;
import isd.resto.modelo.RT_Turno;
import isd.resto.rn.RT_MesasRN;
import isd.resto.rn.RT_MovimientoRN;
import isd.seguridad.web.UsuarioSession;
import java.io.Serializable;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedProperty;
import org.primefaces.event.SelectEvent;



/**
 *
 * @author ctrosch
 */
public class RT_Registraciones extends GenericBean implements Serializable {

    protected @EJB RT_MesasRN mesasRN;
    protected @EJB RT_MovimientoRN movimientoRN;

    @ManagedProperty(value = "#{usuarioSession}")
    protected UsuarioSession usuarioSession;

    @ManagedProperty(value = "#{buscadorProductoBean}")
    protected BuscadorProductoBean buscadorProductoBean;

    protected RT_Movimiento m;
    protected RT_Mesa mesa;
    protected RT_Mozo mozo;
    protected String notas;
    protected ST_Producto producto;
    protected Integer cantidad;
    protected RT_ItemMovimiento item;
    protected GR_Comprobante comprobante;

    protected List<RT_Mesa> mesas;
    protected Date fechaRegistracion;
    private   Date fechaRegistracionCorrecta;
    protected boolean esFechaRegistracionCorrecta;
    protected RT_Turno turno;
    

    /** Creates a new instance of FC_Movimiento */
    public RT_Registraciones() {

        item = new RT_ItemMovimiento();
    }

    @PostConstruct
    private void initBean(){

        try {
            cantidad = 0;
            mesas = mesasRN.getLista();            
            fechaRegistracionCorrecta = selecionarFechaRegistracion();
            fechaRegistracion = selecionarFechaRegistracion();
            seleccionarTurno();

        } catch (Exception e) {

            JsfUtil.addErrorMessage("No es posible iniciar el bean:" + e.getMessage() );
        }
    }   

    public void nuevoMovimiento(){

        try {
            if(mesa==null){
                JsfUtil.addErrorMessage("Seleccione una mesa por favor");
            }

            m = movimientoRN.nuevoMovimiento("RT", "TD001");               
            m.setMesa(mesa);

            if(mozo!=null){
                m.setMozo(mozo);
            }

            mesa.setEstado(RT_MesaEstado.OCUPADA);
            mesa.setMovimiento(m);
            
        }catch(Exception e) {

            JsfUtil.addErrorMessage(e.getMessage());
        }
    }

    public void guardar(boolean  nuevo){

        try {
            movimientoRN.guardar(m);
            JsfUtil.addInfoMessage("El documento "+m.getComprobante().getDescrp()+"-"+m.getNrofor()+" se guardó correctamente","");

            if(nuevo){
                nuevoMovimiento();
            }

        } catch (Exception ex) {

            JsfUtil.addErrorMessage(ex.getMessage());
        }
    }

    public void cerrarMesa(){
        try {
            if (mesa == null) {
                JsfUtil.addErrorMessage("No existe una mesa seleccionada");
                return;
            }
            if (m == null) {
                JsfUtil.addErrorMessage("No existe movimiento a cerrar");
                return;
            }
            movimientoRN.cerrarMesa(m);
            m = null;
            mesa.setEstado(RT_MesaEstado.LIBRE);
            JsfUtil.addInfoMessage("La mesa fue cerrada exitosamente");
        } catch (Exception ex) {
            JsfUtil.addErrorMessage("Error al cerrar la mesa "+ ex.getMessage());
        }
    }

    public void agregarItem(){

        try {

            if(!puedoAgregarItem()) return;

            item = new RT_ItemMovimiento(m);
            item.setCantidad(cantidad);
            item.setProducto(producto);
            item.setPrecio(producto.getPrecioVenta());
            item.setTotalLinea(item.getPrecio().multiply(new BigDecimal(cantidad)));
            m.getItems().add(item);

            cantidad = 0;
            producto = null;

            movimientoRN.guardar(m);
            JsfUtil.addInfoMessage("El produco se agregó correctamente");

        } catch (Exception ex) {
            ex.printStackTrace();
            JsfUtil.addErrorMessage(ex.getMessage());
        }
    }

    public void eliminarItem(RT_ItemMovimiento nItem){

        if(movimientoRN.eliminarItemProducto(m, nItem)){
            JsfUtil.addWarningMessage("Se ha borrado el item "+ nItem.getProducto().getDescrp() + "");
        }else{
            JsfUtil.addWarningMessage("No se ha borrado el item "+ nItem.getProducto().getDescrp() + "");
        }
    }

    public boolean puedoAgregarItem(){

        if(cantidad==null || cantidad <=0){
            JsfUtil.addErrorMessage("Ingrese un valor de cantidad válido. Mayor a 0");
            return false;
        }

        if(producto==null){
            JsfUtil.addErrorMessage("Seleccione un producto para agregar");
            return false;
        }

        if(producto.getPrecioVenta()==null){
            JsfUtil.addErrorMessage("El producto seleccionado no tiene precio de venta asignado");
            return false;
        }

        return true;
    }

    public void seleccionar(RT_Movimiento m){
        this.m = m;
    }

    public void seleccionarMesa(RT_Mesa ms){

        validarFechaRegistracion();

        mesa = ms;
        mozo = null;
        
        if(mesa.getMovimiento()!=null){
            m = mesa.getMovimiento();
        }else{
            m = null;
        }
    }

    public void sincronizarMesas(){

        if(mesas==null) return;
        
        List<RT_Movimiento> movimientos = movimientoRN.getMovimientosNoCerrados(fechaRegistracion);

        for(RT_Mesa mes : mesas){

            mes.setMovimiento(null);
            mes.setEstado(RT_MesaEstado.LIBRE);

            for(RT_Movimiento mov: movimientos){
                
                if(mes.getEstado().equals(RT_MesaEstado.LIBRE) && mes.equals(mov.getMesa())){
                    mes.setMovimiento(mov);
                    mes.setEstado(RT_MesaEstado.OCUPADA);                    
                }
            }
        }
    }

    public void handleDateSelect(SelectEvent event) {

        SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
        fechaRegistracion = (Date) event.getObject();
        sincronizarMesas();
        mesa = null;
        m = null;
        JsfUtil.addWarningMessage("Se ha modificado la fecha de registración por " + format.format(event.getObject()));

        validarFechaRegistracion();

        if(!esFechaRegistracionCorrecta){
            JsfUtil.addWarningMessage("No es la fecha actual, no puede abrir nuevas mesas");
        }
    }

    public BigDecimal getTotalMovimiento(){

        BigDecimal total = BigDecimal.ZERO;

        if(m.getItems()==null) return total;

        for(RT_ItemMovimiento im:m.getItems()){

            total = total.add(im.getTotalLinea());
        }

        return total;
    }

     private void seleccionarTurno() {

        Calendar fechaComparacion = Calendar.getInstance();

        if(fechaComparacion.get(Calendar.HOUR_OF_DAY)< 7
                || fechaComparacion.get(Calendar.HOUR_OF_DAY)> 17){
            turno = RT_Turno.CENA;
        }else{
            turno = RT_Turno.ALMUERZO;
        }
    }

    private Date selecionarFechaRegistracion() {

        Calendar fechaComparacion = Calendar.getInstance();

        if(fechaComparacion.get(Calendar.HOUR_OF_DAY)>= 0
                && fechaComparacion.get(Calendar.HOUR_OF_DAY)< 7){
            //Si son las primeras horas del día, tomamos fecha registración dia anterior

            // Restamos 1 día
            fechaComparacion.add(Calendar.DAY_OF_MONTH, -1);

            return fechaComparacion.getTime();

        }else{
            //Tomamos fecha del día
            return new Date();
        }
    }

    public void validarFechaRegistracion(){

        Calendar frc = Calendar.getInstance();
        Calendar fr  = Calendar.getInstance();
        
        frc.setTime(fechaRegistracionCorrecta);
        fr.setTime(fechaRegistracion);

        if(frc.get(Calendar.DAY_OF_YEAR) == fr.get(Calendar.DAY_OF_YEAR)){
            esFechaRegistracionCorrecta = true;
        }else{
            esFechaRegistracionCorrecta = false;
        }
    }


    public void imprimir(){

        try {
//            System.out.println("Nombre reporte " + m.getFormulario().getNombreReporte());
//
//            if (m.getFormulario().getNombreReporte()==null){
//                throw new ExcepcionGeneralSistema("El comprobante no tienen reporte asociado");
//            }
//
//            //JasperReport masterReport = (JasperReport) JRLoader.loadObject(getClass().getClassLoader().getResourceAsStream("/isd/produccion/reporte/"+ m.getFormulario().getNombreReporte()+".jasper"));
//            JasperReport masterReport = (JasperReport) JRLoader.loadObject(getClass().getClassLoader().getResourceAsStream( m.getFormulario().getNombreReporte()+".jasper"));
//
//            Map parameters = new HashMap();
//            parameters.put("MODFOR", m.getModfor());
//            parameters.put("CODFOR", m.getCodfor());
//            parameters.put("NROFOR", m.getNrofor());
//
//            empresaRN.cargarDatosEmpresa(parameters);
//
//            String nombreArchivo = m.getComprobante().getCodigo()+"-"+m.getNrofor();
//
//            ReportFactory reportFactory = new ReportFactory();
//            reportFactory.verReportePDF(masterReport, nombreArchivo, parameters);

        } catch (NullPointerException npe) {
            JsfUtil.addErrorMessage("No se encontró el archivo: " + m.getFormulario().getNombreReporte()+".jasper");
        } catch (Exception e){
            e.printStackTrace();
            JsfUtil.addErrorMessage("No se puede imprimir a pdf " + e.getMessage());
        }
    }

    public BuscadorProductoBean getBuscadorProductoBean() {
        return buscadorProductoBean;
    }

    public void setBuscadorProductoBean(BuscadorProductoBean buscadorProductoBean) {
        this.buscadorProductoBean = buscadorProductoBean;
    }

    public Map<String, String> getFiltroDetalle() {
        return filtroDetalle;
    }

    public void setFiltroDetalle(Map<String, String> filtroDetalle) {
        this.filtroDetalle = filtroDetalle;
    }

    public Map<String, String> getFiltroGrupo() {
        return filtroGrupo;
    }

    public void setFiltroGrupo(Map<String, String> filtroGrupo) {
        this.filtroGrupo = filtroGrupo;
    }

    public RT_Movimiento getM() {
        return m;
    }

    public void setM(RT_Movimiento m) {
        this.m = m;
    }
    
    public UsuarioSession getUsuarioSession() {
        return usuarioSession;
    }

    public void setUsuarioSession(UsuarioSession usuarioSession) {
        this.usuarioSession = usuarioSession;
    }

    public GR_Comprobante getComprobante() {
        return comprobante;
    }

    public void setComprobante(GR_Comprobante comprobante) {
        this.comprobante = comprobante;
    }

    public RT_Mesa getMesa() {
        return mesa;
    }

    public void setMesa(RT_Mesa mesa) {
        this.mesa = mesa;
    }

    public RT_Mozo getMozo() {
        return mozo;
    }

    public void setMozo(RT_Mozo mozo) {
        this.mozo = mozo;
    }

    public String getNotas() {
        return notas;
    }

    public void setNotas(String notas) {
        this.notas = notas;
    }

    public ST_Producto getProducto() {
        return producto;
    }

    public void setProducto(ST_Producto producto) {
        this.producto = producto;
    }

    public RT_ItemMovimiento getItem() {
        return item;
    }

    public void setItem(RT_ItemMovimiento item) {
        this.item = item;
    }
    
    public Integer getCantidad() {
        return cantidad;
    }

    public void setCantidad(Integer cantidad) {
        this.cantidad = cantidad;
    }

    public Date getFechaRegistracion() {
        return fechaRegistracion;
    }

    public void setFechaRegistracion(Date fechaRegistracion) {
        this.fechaRegistracion = fechaRegistracion;
    }

    public List<RT_Mesa> getMesas() {
        return mesas;
    }

    public void setMesas(List<RT_Mesa> mesas) {
        this.mesas = mesas;
    }

    public RT_Turno getTurno() {
        return turno;
    }

    public boolean isEsFechaRegistracionCorrecta() {
        return esFechaRegistracionCorrecta;
    }

    public void setEsFechaRegistracionCorrecta(boolean esFechaRegistracionCorrecta) {
        this.esFechaRegistracionCorrecta = esFechaRegistracionCorrecta;
    }
    
}
